<template>
  <div class="node">
    <xdh-form ref="form" class="design-form" :class="classes" v-bind="form" :model="model" design-mode  :load="load" :edits="true">
      <el-row :gutter="10">
        <el-tabs v-model="tab_id" type="border-card" editable @edit="handleTabsEdit" @tab-click="handleClick">
          <el-tab-pane v-for="item in sortable_item" :key="item.id" :label="item.title" :name="item.id">
            <div style="padding:20px;min-height:300px">
              <draggable :options="dragOptions2" @add="onAdd" @sort="onSort">
                <transition-group class="form-list-group" type="transition" :name="'flip-list'" tag="div" style="min-height:300px">
                  <template v-for="(element,index) in item.content">
                    <Renders :key="element.prop" :index="index" :item="element" @handleChangeVal="val => handleChangeVal(val,element)" />
                  </template>
                </transition-group>
              </draggable>
            </div>
          </el-tab-pane>
        </el-tabs>
      </el-row>

    </xdh-form>
  </div>
</template>

<style lang="stylus" rel="stylesheet/stylus" scoped type="text/stylus">
.node {
  position: relative;
  cursor: pointer;
  user-select: none;
  font-size: 16px;

  // 防止 relative 子元素 margin 穿透
  &::before {
    content: '';
    display: block;
    overflow: hidden;
    height: 0;
    width: 1px;
  }

  &.active {
    // outline: 1px dashed #faad14;
    // box-shadow: inset rgba(102, 88, 88, 0.43) 0px 0px 10px 0px;
  }

  &.dragentered {
    outline: 1px dashed #faad14;
    box-shadow: rgba(102, 88, 88, 0.43) 0px 0px 10px 3px;
  }

  &.mouseovered {
    outline: 1px dotted #faad14;
    // box-shadow: rgba(102, 88, 88, 0.43) 0px 0px 10px 3px;
  }

  .bt {
    z-index: 0;
    left: 0;
    bottom: 0;
    font-size: 12px;
    color: #dddddd;
  }

  > .node-divider {
    height: 10px;
    position: absolute;
    left: 0;
    top: -5px;

    &.hover {
      background: rgba(255, 0, 0, 0.5);
    }
  }

  > .type-icon {
    position: absolute;
    right: 2px;
    top: 2px;
    width: 10px;
    height: 10px;
    font-size: 10px;
    color: #777;
  }
}
</style>
<script type="text/ecmascript-6">
import BaseComponent from '@/widgets/extend/BaseComponent'
import BaseNode from '@/widgets/extend/BaseNode'
import Vue from 'vue'
import draggable from 'vuedraggable'
import Renders from '@/widgets/components/public/renders'
import { mapState, mapGetters } from 'vuex'
import XdhForm from '@/widgets/xdh-form'
import XdhFormItem from '@/widgets/xdh-form/xdh-form-item'
import cloneDeep from 'lodash/cloneDeep'
import modules from '@/widgets/helper/setting'


export default {
  name: 'Node',
  components: { draggable, XdhForm, XdhFormItem, Renders },
  mixins: [BaseNode, BaseComponent],
  props: {
    info: {
      required: true,
      type: Array,
      default() {
        return []
      }
    },
  },
  computed: {
    ...mapState({
      form: state => state.formModel,
      fields: state => state.fields,
      sortable_item: state => state.fields,
      tabsField: state => state.tabsField,
      editField: state => state.editField
    }),
    ...mapGetters(['model']),
    sortable_item_content() {
      return this.$store.state.fields[this.tab_id]
    },
    dragOptions2() {
      return {
        animation: 0,
        ghostClass: 'ghost',
        group: {
          // 只允许放置shared的控件,禁止pull
          put: ['shared']
        }
      }
    },
    classes() {
      return {
        'is-empty': this.fields.length === 0
      }
    }
  },
  watch: {
    sortable_item_content: {
      handler(val, oldval) {
        val['content'].find(n => {
          if (n['dictapi']) {
            this.load = modules['dict'][n['dictapi']]
          }
        })
      }
    },
    active: function (params) {
      if (this.active) {
        console.log(222222, this.$store)
        this.selectNode = this.$store.nodeInfo
        this.selectNodeStacked = window.$vue && window.$vue.stacked
      }
    },
    editType: {
      handler(val, oldval) {
        window.EDIT_TYPE = String(val).toUpperCase()
        this.previewInfo = cloneDeep(this.info)
        this.ema && this.ema.fire('edit-type.change', window.EDIT_TYPE)
        if (window.EDIT_TYPE == 'EDITOR' && this.ema && this.selectNode) {
          this.$nextTick(() => {
            this.ema.fire('select.one', this.selectNode.id)
          })
        }
      },
      immediate: true
    },
    $route(to,from){
      this.$router.go(0);
    }
  },
  data: function () {
    return {
      tab_id: '0',
      // info: {},
      packedNodeStack: [],
      previewInfo: null,
      selectNode: null,
      selectNodeStacked: true,
      editType: 'editor',
      formData: {},
      showHelper: null,
      dragging: false,
      ismousedown: false,
      load: null
    }
  },
  beforeCreate: function () {
  },
  created: function () {
    //TODO：切换预览模式返回的时候需要
    if(this.sortable_item_content){
      this.sortable_item_content['content'].find(n => {
      if (n['dictapi']) {
        this.load = modules['dict'][n['dictapi']]
      }
    })
    }

  },
  mounted: function () {
    console.log(this.sortable_item_content)
    this.selectNode = this.$store.state.nodeInfo
    console.log(222222, this.selectNode)
    this.selectNodeStacked = window.$vue && window.$vue.stacked

    this.ema.bind('select.oneInfo', ({ vm }) => {
      console.log('scene', vm.nodeInfo)
      this.selectNode = vm.nodeInfo
      this.selectNodeStacked = vm.stacked
    })
    this.ema.bind('select.noOne', () => {
      this.selectNode = null
      this.selectNodeStacked = true
    })
    this.ema.bind('nodeInfo.replace', info => {
      this.info = info
    })
    this.ema.bind('nodeInfo.change', () => {
      this.info = window.Editor.nodeInfo
    })
    this.ema.bind('packedNode.push', (node) => {
      this.packedNodeStack.push(node)
      this.info = node
    })
    this.ema.bind('packedNode.pop', () => {
      this.packedNodeStack.pop()
      const len = this.packedNodeStack.length
      this.info = len == 0 ? window.Editor.nodeInfo : this.packedNodeStack[len - 1]
    })
    this.bindMove()
    this.bindLock()
    window.$app = this
  },
  methods: {
    handleClick(tab, event) {
      console.log(tab, event)
      const tabs = this.fields
      const activeName = this.tab_id
      const item = tabs.filter(tab => tab.id == activeName)
      const info = Object.assign({}, item[0])
console.log(info,activeName,'wqewqewqeqewqeq')
      this.$store.commit('setEditTabsField', info)
    },
    handleTabsEdit(targetName, action) {
      console.log(targetName, action)
      if (action === 'add') {
        var tabIndex = this.fields.length - 1
        const newTabName = ++tabIndex + ''

        const tab = {
          title: 'New Tab',
          id: newTabName,
          content: []
        }

        this.$store.commit('addTabsField', { field: tab, index: tabIndex })
        console.log(tab)
      }

      if (action === 'remove') {
        if (this.fields.length <= 1) {
          return false
        }
        const tabs = this.fields
        let activeName = this.tab_id
        const item = tabs.filter(tab => tab.id == targetName)
        if (this.tab_id == targetName) {
          tabs.forEach((tab, index) => {
            if (tab.id === targetName) {
              const nextTab = tabs[index + 1] || tabs[index - 1]
              if (nextTab) {
                activeName = nextTab.id
              }
            }
          })
        }

        this.tab_id = activeName

        this.$store.commit('removeTabsField', item[0])
      }
    },
    onAdd(e) {
      console.log(this.tab_id)
      const item = e.item._underlying_vm_
      if (item) {
        this.handleDrop(item, e.newIndex)
      }
    },
    clone(data) {
      console.log('clone')
      return JSON.parse(JSON.stringify(data))
    },
    onSort(e) {
      console.log('onSort', e)
      e.tab = this.tab_id;
      // 添加也会触发onSort， 用个变量去来区分
      this.$store.commit('sortFields', e)
    },
    handleDrop(item, index) {
      console.log(item, index)
      if (item) {
        const defaultName = `${item.type}_${new Date().getTime()}`

        const newItem = {
          ...item,
          label: item.title,
          prop: defaultName,
          value: item.value,
          type: item.type,
          tab: this.tab_id
        }
        // delete newItem.title
        console.log(newItem, this.tabsField)
        // this.sortable_item[index] = Object.assign({}, newItem);
        // this.$store.commit('addField', { field: newItem, index: index })
        this.$store.commit('addField', { field: newItem, index: index, tab: this.tab_id })

        //  this.$forceUpdate();
      }
    },
    handleMouseEnter(item) {
      console.log('handleMouseEnter', item)
      if (this.dragging) return
      this.showHelper = item
    },
    handleMouseLeave(item) {
      this.showHelper = null
    },
    handleEditItem(item, index) {
      item.index = index
      const info = Object.assign({}, item)
      this.$store.dispatch('user/setNodeinfo', info)
      this.$store.commit('setEditField', info)
      console.log('handleEditItem', this.$store.getters, 8888888888)
      // this.$store.dispatch('setNoDeInfo',info)
    },
    removeItem(item) {
      const isDepend = !!this.fields.find(n => n.depend === item.prop)
      if (isDepend) {
        this.$message.warning('该字段被其他字段依赖，不能删除')
        return
      }
      this.$store.commit('setEditField', null)
      this.$store.commit('removeField', item,this.tab_id)
    },
    handleDblClick() {
      this.$store.commit('setEditField', null)
    },

    // 控件回填数据
    handleChangeVal(val, element) {
      console.log(123456789)
      this.$set(this.formData, element.obj.name, val)
      // this.formData[element.obj.name] = val;
    },
    scrollChange: function (params) {
      var appWarp = this.$refs['appWarp']
      this.ema.fire('appWarpOffsetChange', {
        top: appWarp.scrollTop,
        left: appWarp.scrollLeft
      })
    },
    /**
     * 背景点击，处理选中内容
     */
    bgClick: function () {
      this.ema.fire('hide.contextMenu')
      this.ema.fire('select.noOne')
    },
    mouseup: function (ev) {
      this.ema.fire('ui.mouseup', ev)
    },
    mousemove: function (ev) {
      this.ema.fire('ui.mousemove', ev)
    },
    dragenter: function (ev) {
      ev.stopPropagation()
    },
    dragover: function (ev) {
      ev.preventDefault()
    },
    deleteNode: function (id) {
      var node = null
      var parent = null
      var key = 0
      var walk = function (datas) {
        datas = datas || []

        for (let index = 0; index < datas.length; index++) {
          const element = datas[index]
          if (element.id === id) {
            node = element
            key = index
            parent = datas
            return
          }
          if (element.child) {
            walk(element.child)
          }
        }
      }
      walk([this.info])
      console.log(parent, key)
      if (!parent) return
      this.$delete(parent, key)
      return node
    },
    bindMove: function () {
      this.ema.bind('move.node', (moveId, targetNode, pos) => {
        console.log('move.node is coming', this.info)
        var moveNode = cloneDeep(this.deleteNode(moveId))
        if (pos) {
          moveNode.style.left = pos.left
          moveNode.style.top = pos.top
        }
        if (targetNode) {
          targetNode.child.push(moveNode)
        }
      })
    },
    lockNode: function (id, flag) {console.log(flag)
      var self = this
      var node = null
      var parent = null
      var key = 0
      var locks = function (arr) {
        for (let i = 0; i < arr.length; i++) {
          self.$set(arr[i], 'lock', flag)
          if (arr[i].child) {
            locks(arr[i].child)
          }
        }
      }
      var walk = function (datas) {
        datas = datas || []
        for (let index = 0; index < datas.length; index++) {
          const element = datas[index]
          console.log(id, element.id)
          if (element.id === id) {
            self.$set(element, 'lock', flag)
            node = element
            key = index
            parent = datas
            if (element.child) {
              locks(element.child)
            }
            return node
          }
          if (element.child) {
            console.log('going')
            walk(element.child)
          }
        }
      }
      walk([this.info])
      console.log(key, parent)
    },
    bindLock: function () {
      this.ema.bind('lock.node', (moveId, flag) => {
        console.log('lock.node is coming', this.info)
        this.lockNode(moveId, flag)
      })
    },
  }
}
</script>

